<template>
  <div class="slider-verification" ref="sliderContainer">
    <div class="slider-left-bg" :style="sliderLeftWidthStyle"></div>
    <div
      class="prompt-text"
      :style="verifySuccess ? promptTextStyleSuccess : {}"
    >
      {{ verifySuccess ? '验证通过' : '向右拖动滑块进行验证' }}
    </div>
    <div
      ref="slider"
      @mousedown="mouseDownHandler($event)"
      :class="{ 'slider-verify-success': verifySuccess }"
      class="slider"
      :style="sliderToLeftStyle"
    ></div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted } from 'vue';

/**
 * 组件名称：
 * 组件描述：
 */
export default defineComponent({
  name: 'SliderVerification',
  components: {},
  props: {
    /**
     * 验证成功提示文字样式
     */
    promptTextStyleSuccess: {
      type: Object,
      default: {
        color: '#ffffff',
      },
    },
    /**
     * 验证成功需要拖动距离倍数，倍数越大验证成功需要拖动的距离越大
     */
    multiple: {
      type: Number,
      default: 2,
    },
  },
  setup(props, context) {
    let sliderState = ref(false);
    let verifySuccess = ref(false);
    let beginClientX = ref(0);
    let maxWidth = ref(0);
    const slideWidth = ref(0);
    const mouseMoveHandler = (e) => {
      if (sliderState.value) {
        let width = (e.clientX - beginClientX.value) / props.multiple;
        if (width > 0 && width <= maxWidth.value) {
          slideWidth.value = width;
        } else if (width > maxWidth.value) {
          slideWidth.value = maxWidth.value;
          verifySuccessFun();
        }
      }
    };
    const moseUpHandler = (e) => {
      sliderState.value = false;
      let width = (e.clientX - beginClientX.value) / props.multiple;
      if (width < maxWidth.value) {
        slideWidth.value = 0;
      }
    };
    const verifySuccessFun = () => {
      verifySuccess.value = true;
      context.emit('statusChange', true);
      document
        .getElementsByTagName('html')[0]
        .removeEventListener('mousemove', mouseMoveHandler);
      document
        .getElementsByTagName('html')[0]
        .removeEventListener('mouseup', moseUpHandler);
      slideWidth.value = maxWidth.value;
    };
    const slider = ref(null);
    const sliderContainer = ref(null);
    onMounted(() => {
      maxWidth.value =
        sliderContainer.value.offsetWidth - slider.value.offsetWidth;
      addListener();
    });
    const addListener = () => {
      document
        .getElementsByTagName('html')[0]
        .addEventListener('mousemove', mouseMoveHandler);
      document
        .getElementsByTagName('html')[0]
        .addEventListener('mouseup', moseUpHandler);
    };
    return {
      sliderContainer,
      slider,
      beginClientX, // 鼠标按下的位置
      sliderState, // 滑块是否可以移动
      maxWidth, // 滑块验证成功需要移动的最大距离
      verifySuccess, // 是否验证成功
      slideWidth, // 滑块滑过的区域宽度
      reset() {
        // 重置
        addListener();
        context.emit('statusChange', false);
        beginClientX.value = 0;
        sliderState.value = false;
        verifySuccess.value = false;
        slideWidth.value = 0;
      },
      mouseDownHandler(e) {
        // 鼠标在滑块上按下事件
        if (!this.verifySuccess) {
          this.sliderState = true;
          this.beginClientX = e.clientX;
        }
      },
    };
  },
  computed: {
    sliderToLeftStyle() {
      return {
        left: this.slideWidth + 'px',
      };
    },
    sliderLeftWidthStyle() {
      return {
        width: this.slideWidth + 'px',
      };
    },
  },
});
</script>
<style scoped lang="scss">
.slider-verification {
  position: relative;
  background-color: rgba(228, 228, 228);
  width: 100%;
  height: 100%;
  line-height: 48px;
  text-align: center;
  user-select: none;
  border-radius: 5px;
}

.slider {
  position: absolute;
  top: 0;
  width: 42px;
  height: 100%;
  cursor: move;
  background: #fff url('../../assets/images/login/move.png') no-repeat center;
  background-size: 30px 30px;
  border: 2px solid rgba(86, 154, 254);
}

.slider-verify-success {
  background: #fff
    url('')
    no-repeat center;
  background-size: 20px 20px;
}

//滑块滑过区域的样式
.slider-left-bg {
  background-color: rgba(86, 154, 254);
  width: 0;
  height: 100%;
  border-radius: 5px 0 0 5px;
}

//提示文本样式
.prompt-text {
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  text-align: center;
  font-size: 14px;
  line-height: 1;
  padding: 13px;
  color: #ffffff;
  opacity: 1;
}
</style>
